/*******************************************************************************\
** cinemagraph:CameraViewController.m
** Created by CZ(cz.devnet@gmail.com) on 11/7/16
**
**  Copyright © 2016 projm. All rights reserved.
\*******************************************************************************/

#import <Masonry/Masonry.h>

#import "CameraViewController.h"

@interface CameraViewController ()
@property (strong, nonatomic) UIView *footerView;
@property (strong, nonatomic) UIView *headerView;
@property (strong, nonatomic) UIButton *cancelBtn;
@property (strong, nonatomic) UIButton *recordBtn;
@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (strong, nonatomic) AVCaptureDevice *backCamera;
@property (strong, nonatomic) AVCaptureDevice *frontCamera;
@property (strong, nonatomic) AVCaptureDeviceInput *captureInput;
@property (strong, nonatomic) AVCaptureVideoDataOutput *captureOutput;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;
@property (nonatomic) BOOL isCapture;
@property (strong, nonatomic) NSTimer *captureTimer;
@property (strong, nonatomic) UILabel *timerLbl;
@property (nonatomic) int remainTime;
@end

@implementation CameraViewController

- (instancetype) init {
    if (self = [super init]) {
        [self.view setBackgroundColor:[UIColor whiteColor]];
    }
    return self;
}

- (void) findDevices {
    NSArray *devices =  [AVCaptureDevice devices];
    for (AVCaptureDevice *device in devices) {
        NSLog(@"device: %ld", (long)device.position);
        if ([device hasMediaType:AVMediaTypeVideo]) {
            if (AVCaptureDevicePositionBack == device.position) {
                _backCamera = device;
            } else if (AVCaptureDevicePositionFront == device.position) {
                _frontCamera = device;
            }
        }
    }
}

- (void) setupDevice {
    if (nil != _backCamera ) {
        NSLog(@"Set focus frame");
    }
}

- (void) buildInput {
    NSError *error;
    _captureInput = [AVCaptureDeviceInput deviceInputWithDevice:_backCamera error:&error ];
    if (nil != error) {
        NSLog(@"build Input error %@", error.localizedDescription);
        return ;
    }
}

- (void) buildOutput {
    _captureOutput = [AVCaptureVideoDataOutput new];
    _captureOutput.videoSettings = @{
                                     (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)
                                     };
    [_captureOutput setAlwaysDiscardsLateVideoFrames: YES];
    dispatch_queue_t videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
    [_captureOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
}

- (void) buildCaptureSession {
    _captureSession = [[AVCaptureSession alloc] init];
    _captureSession.sessionPreset = AVCaptureSessionPresetMedium;
    [_captureSession beginConfiguration];
    if (_captureInput!=nil && [_captureSession canAddInput:_captureInput]) {
        [_captureSession addInput:_captureInput];
    } else {
        NSLog(@"build capture session when add input got error");
        return ;
    }
    
    if (nil!=_captureOutput && [_captureSession canAddOutput:_captureOutput]) {
        [_captureSession addOutput: _captureOutput];
    } else {
        NSLog(@"build capture session when add output got error");
    }
    
    [_captureSession commitConfiguration];
}

- (void) buildCameraView {
    [self.view layoutIfNeeded];
    _captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
    [_captureVideoPreviewLayer setFrame:self.view.bounds];
    [_captureVideoPreviewLayer setVideoGravity: AVLayerVideoGravityResizeAspectFill];
    [self.view.layer insertSublayer:_captureVideoPreviewLayer atIndex:0];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self layoutUI];
    [self findDevices];
    [self setupDevice];
    [self buildInput];
    [self buildOutput];
    [self buildCaptureSession];
    [self buildCameraView];
    if (nil != _captureSession) {
        [_captureSession startRunning];
    }
    _remainTime = 15;
    _isCapture = NO;
}

- (IBAction) onCancel: (id)sender {
    [self stopCapture];
    if (nil != _captureSession) {
        [_captureSession stopRunning];
    }
    
    [self dismissViewControllerAnimated:YES completion:^{
        NSLog(@"back to sketchbook viewcontroller");
    }];
}

- (IBAction) onRecord: (id)sender {
    static BOOL recorded = NO;
    if (!recorded) {
        [_recordBtn setImage:[UIImage imageNamed:@"sb_btn_stop_record"] forState:UIControlStateNormal];
        recorded = YES;
        [self startCapture];
    } else {
        [_recordBtn setImage:[UIImage imageNamed:@"sb_btn_record"] forState:UIControlStateNormal];
        recorded = NO;
        [self stopCapture];
    }
}


- (void) startTimer {
    if (_captureTimer != nil ) {
        [_captureTimer invalidate];
        _captureTimer = nil;
    }
    _captureTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(captureTimerHandler:) userInfo:self repeats:YES];
}

- (void) stopTimer {
    if (_captureTimer != nil ) {
        [_captureTimer invalidate];
        _captureTimer = nil;
    }
}

- (void) startCapture {
    _isCapture = YES;
    [self startTimer];
}

- (void) stopCapture {
    _isCapture = NO;
    [self stopTimer];
}

- (void) layoutUI {
    _footerView = [[UIView alloc]init];
    _headerView = [[UIView alloc] init];
    [self.view addSubview:_headerView];
    [self.view addSubview:_footerView];
    
    _cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [_cancelBtn addTarget:self action:@selector(onCancel:) forControlEvents:UIControlEventTouchDown];
    _recordBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [_recordBtn addTarget:self action:@selector(onRecord:) forControlEvents:UIControlEventTouchDown];
    [_headerView addSubview:_cancelBtn];
    [_footerView addSubview:_recordBtn];
    
    [_headerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
        make.top.equalTo(self.view.mas_top);
        make.height.equalTo(@50);
    }];
    [_headerView setBackgroundColor:[UIColor blackColor]];
    _headerView.alpha = 0.5;
    
    [_footerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
        make.bottom.equalTo(self.view.mas_bottom);
        make.height.equalTo(@100);
    }];
    [_footerView setBackgroundColor:[UIColor blackColor]];
    _footerView.alpha = 0.5;

    [_cancelBtn setImage:[UIImage imageNamed:@"sb_btn_cancel"] forState:UIControlStateNormal];
    [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(@24);
        make.height.equalTo(@24);
        make.right.equalTo(self.view.mas_right).offset(-10);
        make.top.equalTo(self.view.mas_top).offset(12);
    }];

    [_recordBtn setImage:[UIImage imageNamed:@"sb_btn_record"] forState:UIControlStateNormal];
    [_recordBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(@65);
        make.height.equalTo(@65);
        make.centerX.equalTo(_footerView.mas_centerX);
        make.centerY.equalTo(_footerView.mas_centerY);
    }];
    
    _timerLbl = [[UILabel alloc] init];
    [_headerView addSubview:_timerLbl];
    _timerLbl.textAlignment = NSTextAlignmentCenter;
    _timerLbl.textColor = [UIColor whiteColor];
    [_timerLbl mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_headerView.mas_left);
        make.right.equalTo(_headerView.mas_right);
        make.top.equalTo(_headerView.mas_top);
        make.height.equalTo(_headerView.mas_height);
    }];
    _timerLbl.text = @"00:00:15";
}

-(UIStatusBarStyle) preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}

-(BOOL) prefersStatusBarHidden {
    return YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void) captureTimerHandler: (NSTimer *) timer {
    if (_remainTime <0) {
        [self stopCapture];
        return ;
    }
    _timerLbl.text = [NSString stringWithFormat:@"00:00:%02d", _remainTime--];
}


#pragma mark  AVCaptureAudioDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    if (!_isCapture) {
        return ;
    }
    NSLog(@"Capture a frame");
}

@end
